package com.backend.aspect;

import com.backend.annotation.RequireAuth;
import com.backend.annotation.RequireRole;
import com.backend.service.rbac.RoleAuthService;
import com.backend.service.rbac.RoleService;
import com.backend.service.rbac.UserRoleService;
import com.common.exception.AuthException;
import com.common.threadlocal.UserLocal;
import com.pojo.dto.UserDTO;
import com.pojo.vo.AuthVO;
import com.pojo.vo.RoleVO;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.HashSet;
import java.util.List;
import java.util.Set;


@Component
@Aspect
@Slf4j
@Order(2)
public class RequireAuthAspect {
    @Autowired
    RoleAuthService roleAuthService;
    @Autowired
    UserRoleService userRoleService;
    @Autowired
    RoleService roleService;
    /**
     * 切入点
     */
    @Pointcut("execution(* com.backend..*.*(..)) && @annotation(com.backend.annotation.RequireAuth)")
    public void requireAuthPointCut(){}

    /**
     * 校验使用该方法的权限够不够
     */
    @Before("requireAuthPointCut()")
    public void requireAuth(JoinPoint joinPoint) {
        log.info("开始校验权限");
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        RequireAuth annotation = signature.getMethod().getAnnotation(RequireAuth.class);
        String[] auths = annotation.value();
        if (auths == null || auths.length == 0) {
            return ;
        }
        UserDTO userDTO = UserLocal.getCurrentUserDTO();
        List<String> rolesByUserId = userRoleService.getRolesByUserId(userDTO.getId());
        Set<String> set = new HashSet<>();
        for (int i = 0; i < rolesByUserId.size(); i ++) {
            RoleVO role = roleService.getRoleByName(rolesByUserId.get(i));
            List<AuthVO> authsByRoleId = roleAuthService.getAuthsByRoleId(role.getId());
            for (int j = 0; j < authsByRoleId.size(); j ++) {
                set.add(authsByRoleId.get(j).getName());
            }
        }
        for (int i = 0; i < auths.length; i ++) {
            if (set.contains(auths[i])) {
                log.info("用户权限充足");
                return ;
            }
        }
        throw new AuthException("用户权限不足");
    }
}
